#ifndef HTTP_REQUEST_H
#define HTTP_REQUEST_H

#include <map>
#include <string>
#include <QMap>
#include <QByteArray>

// Http请求报文的解析状态
enum class HttpRequestDecodeState {
    kInvalid, //无效
    kInvalidMethod, //无效请求方法
    kInvalidUri, //无效的请求路径
    kInvalidVersion, //无效的协议版本号
    kInvalidHeader, //无效请求头

    kStart, //请求行开始
    kMethod, //请求方法

    kBeforeUrl, //请求连接前的状态，需要'/'开头
    kInUrl, //url处理
    kBeforeUriParamKey, //URL请求参数键之前
    kUriParamKey, //URL请求参数键
    kBeforeUriParamValue, //URL的参数值之前
    kUriParamValue, //URL请求参数值

    kBeforeProtocol, //协议解析之前
    kProtocol, //协议

    kBeforeVersion, //版本开始前
    kVersionSplit, //版本分隔符 '.'
    kVersion, //版本

    kHeaderKey,

    kHeaderBeforeColon, //冒号之前
    kHeaderAfterColon, //冒号
    kHeaderValue, //值

    kWhenCR, //遇到一个回车之后

    kCRLF, //回车换行

    kCRLFCR, //回车换行之后的状态

    kBody, //请求体
    kComplete //完成
};

class HttpRequest
{
public:
    HttpRequest();
    HttpRequest(const HttpRequest &) = default;
    HttpRequest(HttpRequest &&) = default;
    HttpRequest &operator = (const HttpRequest &) = default;
    ~HttpRequest() = default;

    // 解析http报文
    void tryDecode(const QByteArray &httpMessage);
    // 重置状态
    void reset();
    // 获取HTTP method名
    const QByteArray &getMethod() const { return m_method;}
    // 获取 HTTP 的请求行的URL
    const QByteArray &getUrl() const {return m_url;}
    const QMap<QByteArray, QByteArray> &getRequestParams() const {return m_requestParams;}
    //获取协议
    const QByteArray &getProtocol() const {return m_protocol;}
    // 获取版本号
    const QByteArray &getVersion() const {return m_version;}
    // 获取请求头键值对
    const QMap<QByteArray, QByteArray> &getHeaders() const {return m_headers;}
    // 获取对应头部字段的值
    QByteArray getHeader(const QByteArray &key) const;
    // 获取body数据
    const QByteArray &getBody() const {return m_body;}
    //获取当前解析的状态
    HttpRequestDecodeState getDecodeState() const {return m_decodeState;}
    bool keepAlive() const;
    // 判读HTTP报文是否解析完成
    bool gotAll() const {return m_decodeState == HttpRequestDecodeState::kComplete;}
    // 获取已经处理的有效的HTTP消息长度
    size_t getProcessedValidMessageLength() const;

private:
    void parseInternal(const char *buf, size_t size);

private:
    QByteArray m_method; //请求方法
    QByteArray m_url; //请求路径(不包含请求参数)
    QMap<QByteArray, QByteArray> m_requestParams; //请求参数
    QByteArray m_protocol; //协议
    QByteArray m_version; //版本
    QMap<QByteArray, QByteArray> m_headers; //所有的请求头
    QByteArray m_body; //请求体
    size_t m_nextPos; //下一个位置的
    size_t m_bodyLength; //body长度
    size_t m_curScanPos; // 当前解析的位置
    HttpRequestDecodeState m_decodeState; //解析状态
};

#endif // HTTP_REQUEST_H
